package com.example.webcrawler.service.mpl;

import com.example.webcrawler.model.ApiRequest;
import com.example.webcrawler.model.FlowStep;
import com.example.webcrawler.model.FlowTest;
import com.example.webcrawler.service.FlowService;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class FlowServiceImpl implements FlowService {

    private static final Logger logger = LoggerFactory.getLogger(FlowServiceImpl.class);
    private static final ObjectMapper objectMapper = new ObjectMapper();

    // 创建一个可重用的HTTP客户端
    private final HttpClient httpClient = HttpClient.newBuilder()
            .connectTimeout(Duration.ofSeconds(10))
            .build();

    @Autowired
    private DataStorageService dataStorageService;

    @Override
    public List<FlowTest> getAllSavedFlows() {
        return dataStorageService.getAllFlows();
    }

    @Override
    public FlowTest saveFlow(FlowTest flowTest) {
        return dataStorageService.saveFlow(flowTest);
    }

    @Override
    public void deleteFlow(String flowId) {
        boolean success = dataStorageService.deleteFlow(flowId);
        if (!success) {
            throw new RuntimeException("未找到流程ID: " + flowId);
        }
    }

    @Override
    public Map<String, Object> executeFlow(FlowTest flowTest) throws Exception {
        // 执行流程测试中的每个请求
        List<ApiRequest> results = new ArrayList<>();
        Map<String, Object> variables = new HashMap<>();

        for (FlowStep step : flowTest.getSteps()) {
            // 应用变量替换
            ApiRequest request = applyVariables(step.getRequest(), variables);

            // 发送请求
            ApiRequest result = sendRequestInternal(request);
            results.add(result);

            // 提取变量
            extractVariables(result, step.getVariableExtractions(), variables);
        }

        Map<String, Object> response = new HashMap<>();
        response.put("data", results);
        response.put("variables", variables);
        return response;
    }

    @Override
    public List<ApiRequest> getRequestsByFlowId(String flowId) {
        return dataStorageService.getRequestsByFlowId(flowId);
    }

    /**
     * 应用变量替换
     */
    private ApiRequest applyVariables(ApiRequest request, Map<String, Object> variables) {
        ApiRequest result = new ApiRequest();
        result.setMethod(request.getMethod());
        result.setType(request.getType());
        result.setSource(request.getSource());
        result.setStatus(request.getStatus());

        // 替换URL中的变量
        String url = request.getUrl();
        if (url != null) {
            for (Map.Entry<String, Object> entry : variables.entrySet()) {
                String placeholder = "{{" + entry.getKey() + "}}";
                url = url.replace(placeholder, entry.getValue().toString());
            }
        }
        result.setUrl(url);

        // 替换请求体中的变量
        if (request.getRequestBody() != null) {
            String requestBody = request.getRequestBody();
            for (Map.Entry<String, Object> entry : variables.entrySet()) {
                String placeholder = "{{" + entry.getKey() + "}}";
                requestBody = requestBody.replace(placeholder, entry.getValue().toString());
            }
            result.setRequestBody(requestBody);
        }

        // 替换请求头中的变量
        Map<String, String> headers = new HashMap<>();
        if (request.getRequestHeaders() != null) {
            for (Map.Entry<String, String> entry : request.getRequestHeaders().entrySet()) {
                String value = entry.getValue();
                if (value != null) {
                    for (Map.Entry<String, Object> varEntry : variables.entrySet()) {
                        String placeholder = "{{" + varEntry.getKey() + "}}";
                        value = value.replace(placeholder, varEntry.getValue().toString());
                    }
                }
                headers.put(entry.getKey(), value);
            }
        }
        result.setRequestHeaders(headers);

        // 复制响应相关字段
        result.setResponseHeaders(request.getResponseHeaders());
        result.setResponseBody(request.getResponseBody());
        result.setResponseTime(request.getResponseTime());

        return result;
    }

    /**
     * 提取变量
     */
    private void extractVariables(ApiRequest response, Map<String, String> extractions, Map<String, Object> variables) {
        if (extractions == null || extractions.isEmpty()) {
            return;
        }

        try {
            // 解析响应体为JSON
            String responseBody = response.getResponseBody();
            if (responseBody == null || responseBody.trim().isEmpty()) {
                return;
            }

            JsonNode jsonNode = objectMapper.readTree(responseBody);

            for (Map.Entry<String, String> extraction : extractions.entrySet()) {
                try {
                    // 简化版JSONPath提取（仅支持简单的属性访问）
                    String path = extraction.getValue().replace("$.", "");
                    String[] pathParts = path.split("\\.");

                    JsonNode currentNode = jsonNode;
                    for (String part : pathParts) {
                        if (currentNode != null && currentNode.has(part)) {
                            currentNode = currentNode.get(part);
                        } else {
                            currentNode = null;
                            break;
                        }
                    }

                    if (currentNode != null) {
                        variables.put(extraction.getKey(), currentNode.asText());
                    }
                } catch (Exception e) {
                    logger.warn("Failed to extract variable {} with path {}: {}",
                            extraction.getKey(), extraction.getValue(), e.getMessage());
                }
            }
        } catch (Exception e) {
            // 处理解析错误
            logger.warn("Failed to parse response body as JSON: " + e.getMessage());
        }
    }

    /**
     * 内部方法：发送请求并返回响应
     */
    private ApiRequest sendRequestInternal(ApiRequest request) throws IOException, InterruptedException {
        long startTime = System.currentTimeMillis();

        ApiRequest result = new ApiRequest();
        result.setMethod(request.getMethod());
        result.setUrl(request.getUrl());

        // 构建请求
        String method = request.getMethod() != null ? request.getMethod().toUpperCase() : "GET";
        URI uri = URI.create(request.getUrl());
        HttpRequest.Builder requestBuilder = HttpRequest.newBuilder()
                .uri(uri)
                .timeout(Duration.ofSeconds(30));

        // 设置请求方法和请求体
        switch (method) {
            case "GET":
                requestBuilder = requestBuilder.GET();
                break;
            case "POST":
                if (request.getRequestBody() != null) {
                    requestBuilder = requestBuilder.POST(HttpRequest.BodyPublishers.ofString(request.getRequestBody()));
                } else {
                    requestBuilder = requestBuilder.POST(HttpRequest.BodyPublishers.noBody());
                }
                break;
            case "PUT":
                if (request.getRequestBody() != null) {
                    requestBuilder = requestBuilder.PUT(HttpRequest.BodyPublishers.ofString(request.getRequestBody()));
                } else {
                    requestBuilder = requestBuilder.PUT(HttpRequest.BodyPublishers.noBody());
                }
                break;
            case "DELETE":
                requestBuilder = requestBuilder.DELETE();
                break;
            default:
                requestBuilder = requestBuilder.method(method, HttpRequest.BodyPublishers.noBody());
                break;
        }

        // 添加请求头
        if (request.getRequestHeaders() != null) {
            for (Map.Entry<String, String> header : request.getRequestHeaders().entrySet()) {
                requestBuilder = requestBuilder.header(header.getKey(), header.getValue());
            }
        }

        // 发送请求
        HttpResponse<String> response = httpClient.send(requestBuilder.build(),
                HttpResponse.BodyHandlers.ofString());

        // 设置响应结果
        result.setStatus(response.statusCode());
        result.setResponseBody(response.body());
        result.setResponseTime(System.currentTimeMillis() - startTime);

        // 设置响应头
        Map<String, String> responseHeaders = new HashMap<>();
        response.headers().map().forEach((key, values) -> {
            if (values != null && !values.isEmpty()) {
                responseHeaders.put(key, values.get(0));
            }
        });
        result.setResponseHeaders(responseHeaders);

        return result;
    }
}
